<?php

require_once 'database_engine/common_engine.php';
require_once 'components/input_values.php';
require_once 'components/renderer.php';
require_once 'components/utils/string_utils.php';

abstract class EditProperties
{
    public abstract function ExtractSingleValue(IInputValues $input);

    public abstract function Render(Renderer $renderer);

    public abstract function SetValue($value);
    
    public abstract function GetValue();
}

class TextEditProperties extends EditProperties
{
    private $editorName;
    private $value;

    public function __construct($editorName)
    {
        $this->editorName = $editorName;
        $this->value = null;
    }

    public function ExtractSingleValue(IInputValues $input)
    {
        if ($input->HasValue($this->editorName))
            return $input->GetValue($this->editorName);
        else
            return null;
    }

    public function SetValue($value)
    {
        $this->value = $value;
    }

    public function GetValue()
    {
        return $this->value;
    }

    /**
     * @param Renderer $renderer
     * @return string
     */
    public function Render(Renderer $renderer)
    {
        return StringUtils::Format(
            '<input name="%s" id="%s" class="pgui-text-edit" value="%s"/>',
            $this->editorName,
            $this->editorName,
            $this->GetValue()
        );
    }
}

class VerticalGridRow
{
    /**
     * @var string
     */
    private $caption;

    /**
     * @param string $caption
     */
    public function __construct($caption)
    {
        $this->caption = $caption;
    }

    /**
     * @param EditProperties $editProperties
     * @return void
     */
    public function SetEditProperties(EditProperties $editProperties)
    { }

    /**
     * @return EditProperties
     */
    public function GetEditProperties()
    { }

    public function ProcessPost(IInputValues $input)
    { }

    /**
     * @return string
     */
    public function GetCaption() { return $this->caption; }

    /**
     * @param string $caption
     * @return void
     */
    public function SetCaption($caption) { $this->caption = $caption; }

    /**
     * @return mixed
     */
    public function GetValue()
    { }

    public function Render(Renderer $renderer)
    { }
}

class FieldBindedVerticalGridRow extends VerticalGridRow
{
    /** @var string */
    private $fieldName;

    /** @var EditProperties */
    private $editProperties;

    /** @var \IEditableDataRecord */
    private $dataRecord;

    /**
     * @param string $fieldName
     */
    public function __construct($caption, $fieldName, IEditableDataRecord $dataRecord)
    {
        parent::__construct($caption);
        $this->fieldName = $fieldName;
        $this->dataRecord = $dataRecord;
    }

    /**
     * @param EditProperties $editProperties
     * @return void
     */
    public function SetEditProperties(EditProperties $editProperties)
    {
        $this->editProperties = $editProperties;
    }

    /**
     * @return EditProperties
     */
    public function GetEditProperties()
    {
        return $this->editProperties;
    }
    
    /**
     * @param IInputValues $input
     * @param IEditableDataRecord $dataWriter
     * @return void
     */
    public function ProcessPost(IInputValues $input)
    {
        $value = $this->editProperties->ExtractSingleValue($input);
        $this->dataRecord->SetFieldValueByName($this->fieldName, $value);
    }

    /**
     * @param Renderer $renderer
     * @return string
     */
    public function Render(Renderer $renderer)
    {
        $this->GetEditProperties()->SetValue($this->GetValue());
        $editor = $this->GetEditProperties()->Render($renderer);

        $row = array(
            'Editor' => $editor,
            'Caption' => $this->GetCaption()
        );

        return $renderer->Render('vertical_grid_row', array(
            'Row' => $row
        ));
    }

    /**
     * @return mixed
     */
    public function GetValue()
    {
        return $this->dataRecord->GetFieldValueByName($this->fieldName);
    }
}

class VerticalGrid
{
    /** @var \IEditableDataRecord */
    private $dataWriter;

    /** @var VerticalGridRow[] */
    private $rows;
    
    public function __construct(IEditableDataRecord $dataWriter)
    {
        $this->dataWriter = $dataWriter;
        $this->rows = array();
    }

    /**
     * @param string $caption
     * @param string $fieldName
     * @return VerticalGridRow
     */
    public function AddFieldRow($caption, $fieldName)
    {
        $result = new FieldBindedVerticalGridRow($caption, $fieldName, $this->dataWriter);
        $this->rows[] = $result;
        return $result;
    }   

    /**
     * @param Renderer $renderer
     * @return string
     */
    public function RenderGridContainer(Renderer $renderer)
    {
        return '<div class="pgui-vertical-grid"></div>';
    }

    private function GetGridData(Renderer $renderer)
    {
        $rowsData = array();

        $primaryKeyValues = array();
        $primaryKeyIndex = 0;
        foreach(GetPrimaryKeyValues($this->dataWriter) as $value)
        {
            $primaryKeyValues[] = array(
                'Value' => $value,
                'Index' => $primaryKeyIndex
            );
            $primaryKeyIndex++;
        }

        foreach($this->rows as $row)
            $rowsData[] = array(
                'Html' => $row->Render($renderer)
            );

        $result = array(
            'Rows' => $rowsData,
            'DataUrl' => 'test_page.php?c=vertical_grid',
            'PrimaryKeyValues' => $primaryKeyValues
        );
        
        return $result;
    }

    /**
     * @param Renderer $renderer
     * @return string
     */
    public function RenderFullGrid(Renderer $renderer)
    {
        return $renderer->Render('vertical_grid', array(
            'Grid' => $this->GetGridData($renderer)
        ));
    }

    public function RenderGridContent(Renderer $renderer)
    {
        return $renderer->Render('vertical_grid_content', array(
            'Grid' => $this->GetGridData($renderer)
        ));
    }

    public function ProcessPost(IInputValues $post)
    {
        foreach($this->rows as $row)
            $row->ProcessPost($post, $this->dataWriter);
    }

    /**
     * @param IInputValues $post
     * @return string[]
     */
    public function ExtractPrimaryKeyValuesFromPost(IInputValues $post)
    {
        $result = array();

        $primaryKeyIndex = 0;
        
        foreach(GetPrimaryKeyFieldNames($this->dataWriter) as $primaryKeyFieldName)
        {
            $value = $post->GetValue('pk' . $primaryKeyIndex);
            $result[$primaryKeyFieldName] = $value;
            $primaryKeyIndex++;
        }

        return $result;
    }
}

?>